#pragma once
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>

#include "logger.hpp"
#include "mysql.hpp"
// #include "relation.hxx"
#include "relation-odb.hxx"

namespace im{

    class RelationTable {
        typedef odb::query<Relation> query;
        typedef odb::result<Relation> result;
    public:
        using ptr = std::shared_ptr<RelationTable>;
        RelationTable(const std::shared_ptr<odb::database>& db):_db(db){}

        // 添加好友关系
        bool insert(const std::string& uid, const std::string& friend_uid){
            // 需要注意的是两个用户结为好友时，需要添加 (1,2),(2,1) 两条数据
            try{
                odb::transaction t(_db->begin());
                Relation rel1(uid, friend_uid);
                Relation rel2(friend_uid, uid);
                _db->persist(rel1);
                _db->persist(rel2);
                t.commit();
            } catch(const std::exception& e) {
                LOG_CRITICAL("新增用户好友关系信息失败 {}-{}:{}！", uid, friend_uid, e.what());
                return false;
            }
            return true;    
        }

        // 删除好友关系        
        bool remove(const std::string& uid, const std::string& friend_uid){
            try{
                odb::transaction t(_db->begin());
                _db->erase_query<Relation>(query::user_id == uid && query::peer_id == friend_uid);
                _db->erase_query<Relation>(query::user_id == friend_uid && query::peer_id == uid);
                t.commit();
            } catch(const std::exception& e) {
                LOG_CRITICAL("删除好友关系信息失败 {}-{}:{}！", uid, friend_uid, e.what());
                return false;
            }
            return true; 
        }

        // 判断用户 uid 和 friend_uid 是否为好友
        bool is_friend(const std::string& uid, const std::string& friend_uid){
            bool flag = false;
            try{
                odb::transaction t(_db->begin());
                result r(_db->query<Relation>(query::user_id == uid && query::peer_id == friend_uid));
                flag = !r.empty();
                t.commit();
            } catch(const std::exception& e) {
                LOG_CRITICAL("获取用户好友关系失败:{}-{}-{}！", uid, friend_uid, e.what());
            }
            return flag; 
        }

        // 获取用户ID为 uid 的好友列表
        std::vector<std::string> friends(const std::string& uid){
            std::vector<std::string> friends;
            try{
                odb::transaction t(_db->begin());
                result r(_db->query<Relation>(query::user_id == uid));
                for(auto& rel : r){
                    friends.push_back(rel.peer_id());
                }
                t.commit();
            } catch (const std::exception& e) {
                LOG_CRITICAL("获取用户好友关系失败 - 用户{}的好友个数:{} - {}！", uid, friends.size(), e.what());
            }
            return friends;
        }

    private:
        std::shared_ptr<odb::database> _db;
    };
}